☰ See All Chapters |
Generic types as a form of qualifier
When multiple beans of same type exist for injection, spring throws NoUniqueBeanDefinitionException. One solution to solve this is by using @Qualifier annotation.
In addition to the @Qualifier annotation, it is also possible to use Java generic types as an implicit form of qualification. If Car is an interface and Audi, Ferrari are two different implementations of Car, Suppose if Car variable is used with @Autowired annotation, spring has a conflict for injecting the bean. This can be solved by using @Qualifier annotation along with @Autowired annotation.
If Car is a generic interface then Car variable can be created by specifying type for the generic parameter. Using this generic type spring inject the bean of that type. This feature works only if interface is generic interface.
If spring has to inject for generic interface type variable and variable has specified type for the generic parameter, then using that generic type spring inject the bean of that type. This feature works only if interface is generic interface.
Let us see an example for Spring Autowiring of Generic Types.
Spring Autowiring of Generic Types Example
pom.xml
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.java4coding</groupId> <artifactId>Spring4.0_Generics_Type_As_Qualifier</artifactId> <version>0.0.1-SNAPSHOT</version>
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> </dependencies>
<properties> <spring.version>4.2.4.RELEASE</spring.version> </properties>
</project> |
Car.java
package com.java4coding.car; public interface Car<T> { public abstract void printCarName(); } |
Audi.java
package com.java4coding.car;
import org.springframework.stereotype.Component;
@Component public class Audi implements Car{
public void printCarName() { System.out.println("Audi"); } }
|
Ferrari.java
package com.java4coding.car;
import org.springframework.stereotype.Component;
@Component public class Ferrari implements Car{
public void printCarName() { System.out.println("Ferrari"); } } |
Demo.java
package com.java4coding.demo;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;
import com.java4coding.car.Audi; import com.java4coding.car.Car; import com.java4coding.car.Ferrari;
@Configuration @ComponentScan(basePackages = { "com.java4coding.car" }) public class Demo {
@Autowired Car<Audi> audi;
@Autowired Car<Ferrari> ferrari;
public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext( Demo.class); Demo demo = (Demo)ctx.getBean("demo"); demo.audi.printCarName(); demo.ferrari.printCarName(); ctx.close(); } } |
Output:
All Chapters